package com.kmxd.ams.app.use;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.kmxd.ams.app.event.AmsEventPublisher;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.event.statistices.StatisticsUsingOpEvent;
import com.kmxd.ams.client.search.ISearchSvc;
import com.kmxd.ams.client.search.dto.SearchAuthCheckDTO;
import com.kmxd.ams.client.search.dto.SearchViewDTO;
import com.kmxd.ams.client.search.vo.SearchViewVO;
import com.kmxd.ams.client.use.IUseExcerptInfoSvc;
import com.kmxd.ams.client.use.dto.UseExcerptInfoAddDTO;
import com.kmxd.ams.client.use.dto.UseExcerptInfoEditDTO;
import com.kmxd.ams.client.use.dto.UseExcerptInfoQueryDTO;
import com.kmxd.ams.client.use.vo.UseExcerptInfoListVO;
import com.kmxd.ams.client.use.vo.UseExcerptInfoVO;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.UseTypeEnum;
import com.kmxd.ams.core.common.query.QueryGen;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.core.util.SecurityUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveType;
import com.kmxd.ams.infra.use.entity.UseExcerptInfo;
import com.kmxd.ams.infra.use.mapper.UseExcerptInfoMapper;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 摘录 服务实现类
 *
 * @author nickbi
 * @since 2023-01-11
 */
@Service
@AllArgsConstructor
public class UseExcerptInfoSvcImpl extends ServiceImpl<UseExcerptInfoMapper, UseExcerptInfo>
    implements IUseExcerptInfoSvc {

  private final AmsEventPublisher amsEventPublisher;
  private final IArchiveTypeSvc archiveTypeSvc;
  private UseExcerptInfoMapper useExcerptInfoMapper;

  @Override
  public Page<UseExcerptInfoListVO> selectPage(Page reqPage, UseExcerptInfoQueryDTO req) {
    LambdaQueryWrapper<UseExcerptInfo> queryWrapper =
        QueryGen.init(new QueryWrapper<UseExcerptInfo>(), req).lambda();

    if (!SecurityUtil.isRootGroup()) {
      queryWrapper.eq(UseExcerptInfo::getUserId, SecurityUtil.getUserId());
    }
    Page<UseExcerptInfo> page = useExcerptInfoMapper.selectPage(reqPage, queryWrapper);
    Page<UseExcerptInfoListVO> voPage = BeanUtil.copyProperties(page, Page.class);
    voPage.setRecords(convertList(page.getRecords()));
    return voPage;
  }

  @Override
  public List<UseExcerptInfoListVO> selectList(UseExcerptInfoQueryDTO req) {
    LambdaQueryWrapper<UseExcerptInfo> queryWrapper =
        QueryGen.init(new QueryWrapper<UseExcerptInfo>(), req).lambda();
    if (!SecurityUtil.isRootGroup()) {
      queryWrapper.eq(UseExcerptInfo::getUserId, SecurityUtil.getUserId());
    }
    queryWrapper.in(
        StrUtil.isNotBlank(req.getIds()), UseExcerptInfo::getId, IdUtil.split(req.getIds()));
    List<UseExcerptInfo> list = useExcerptInfoMapper.selectList(queryWrapper);
    return convertList(list);
  }

  private List<UseExcerptInfoListVO> convertList(List<UseExcerptInfo> list) {
    if (ObjectUtil.isEmpty(list)) {
      return Lists.newArrayList();
    }
    List<Long> archTypeIds =
        list.stream().map(UseExcerptInfo::getArchTypeId).collect(Collectors.toList());
    List<ArchiveType> archTypeList = archiveTypeSvc.listByIds(archTypeIds);
    Map<Long, String> archTypeNameMap =
        archTypeList.stream().collect(Collectors.toMap(ArchiveType::getId, ArchiveType::getName));
    return list.stream()
        .map(
            item -> {
              UseExcerptInfoListVO vo = BeanUtil.copyProperties(item, UseExcerptInfoListVO.class);
              vo.setArchTypeName(archTypeNameMap.get(item.getArchTypeId()));
              return vo;
            })
        .collect(Collectors.toList());
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void add(UseExcerptInfoAddDTO req) {
    SearchViewDTO dto = new SearchViewDTO();
    dto.setArchTypeId(req.getArchTypeId());
    dto.setTableId(req.getTableId());
    dto.setId(req.getArchId());
    ISearchSvc searchSvc = SpringUtil.getBean(ISearchSvc.class);
    SearchViewVO view = searchSvc.view(dto);
    SearchAuthCheckDTO checkDTO = new SearchAuthCheckDTO();
    checkDTO.setArchTypeId(req.getArchTypeId());
    checkDTO.setTableId(req.getTableId());
    checkDTO.setId(req.getArchId());
    checkDTO.setUseTypeEnum(UseTypeEnum.EXTRACT);
    boolean auth = searchSvc.checkAuth(checkDTO);
    if (!auth) {
      throw BizTipException.instance(ErrorCode.SEARCH_NO_AUTH, "没有摘录权限");
    }
    UseExcerptInfo entity = BeanUtil.copyProperties(req, UseExcerptInfo.class);
    entity.setComId(SecurityUtil.getCropId());
    entity.setFondsId(SecurityUtil.getFondsId());
    entity.setDeptId(SecurityUtil.getLoginUser().getDeptId());
    entity.setUserId(SecurityUtil.getUserId());
    useExcerptInfoMapper.insert(entity);
    // 记录使用日志
    amsEventPublisher.publishEvent(
        StatisticsUsingOpEvent.builder()
            .comId(SecurityUtil.getCropId())
            .fondsId(SecurityUtil.getFondsId())
            .archTypeId(req.getArchTypeId())
            .tableId(req.getTableId())
            .archId(req.getId())
            .userName(SecurityUtil.getUsername())
            .op(UseTypeEnum.EXTRACT.getType())
            .realOp(UseTypeEnum.EXTRACT.getType())
            .deptId(SecurityUtil.getLoginUser().getDeptId())
            .build());
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void edit(UseExcerptInfoEditDTO req) {
    UseExcerptInfo entity = BeanUtil.copyProperties(req, UseExcerptInfo.class);
    useExcerptInfoMapper.updateById(entity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void remove(String ids) {
    Set<Long> idList = IdUtil.split(ids);
    this.baseMapper.deleteBatchIds(idList);
  }

  @Override
  public UseExcerptInfoVO view(Long id) {
    UseExcerptInfo entity = useExcerptInfoMapper.selectById(id);
    return BeanUtil.copyProperties(entity, UseExcerptInfoVO.class);
  }
}
